﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

using Montador;
using XYSC_1;

namespace IDE
{
    public partial class frmPrincipal : Form
    {
        // métodos existencias do formulário
        //
        public frmPrincipal()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Maximized;
            this.Controls.Add(ProtT);
            this.Controls.Add(txtProtocolo.lblProtocolo());
            AtuOPL(ref OPL);
            AtuOPM(ref OPM);
        }

        // Elementos visiveis e os dados para traz
        //
        dgvLinhas LIN;
        txtProtocolo ProtT = new txtProtocolo();
        optLista OPL = new optLista();
        frmList LIS;

        // Variaveis controlando arquivo de fonte
        //
        string ArquiDirAtual = "";
        string ArquiNomeAtual = "";  // sem extensão
        const string ArquiFonteExt = "mn5";
        const string ArquiReloExt = "ob5";
        const string ArquiExeExt = "ex5";
        bool ArquiPersistente = false;  // arquivo fonte existe no disco
        bool ArquiCongruente = true;  // Programa no montador congruente com origem

        // Variaveis controlando o montador e o vinculador
        //
        static string TipoProcPadrao = "XYSC1_V2";
        Montador.Montador MON = new Montador.Montador(TipoProcPadrao);
        OpcMont OPM = new OpcMont();


        // Operações sob controle do menu
        //
        //

        // menu programa
        //
        private void novoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Criar novo programa átual

            // resolver conflito com dados presentes e não salvo
            DialogResult dd;
            if (!ArquiCongruente)
            {
                dd = MessageBox.Show("Com esta operação o programa átual será perdido. Continuar?",
                                     "Alerta",
                                     MessageBoxButtons.OKCancel);
                if (dd != System.Windows.Forms.DialogResult.OK) return;  // die another day
            }

            
            // novo programa
            MON.NovoProg();
            //ProcAtual = MON.PROG.TipoProc;
            ArquiCongruente = true;
            ArquiPersistente = false;

            if (LIN != null) this.Controls.Remove(LIN);
            LIN = new dgvLinhas(MON.PROG.TipoProc, MON.PROG.Linhas, ResetCongru);
            this.Controls.Add(LIN);

            ProtT.Clear();

        }
        private void abrirToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // selcionar arquivo e ler programa dai

            // resolver conflito com dados presentes e não salvo
            DialogResult dd;
            if (!ArquiCongruente)
            {
                dd = MessageBox.Show("Com esta operação o programa átual será perdido. Continuar?",
                                     "Alerta",
                                     MessageBoxButtons.OKCancel);
                if (dd != System.Windows.Forms.DialogResult.OK) return;  // die another day
            }


            // selecionar e abrir arquivo fonte
            OpenFileDialog ofdFonte = new OpenFileDialog();

            ofdFonte.AddExtension = true;
            ofdFonte.CheckFileExists = true;
            ofdFonte.CheckPathExists = true;
            ofdFonte.DefaultExt = ArquiFonteExt;
            ofdFonte.Multiselect = false;
            ofdFonte.RestoreDirectory = true;
            ofdFonte.Title = "Abrir arquivo fonte do Montador-J5";
            ofdFonte.ValidateNames = true;

            if (ArquiDirAtual != "") ofdFonte.InitialDirectory = ArquiDirAtual;
            dd = ofdFonte.ShowDialog();

            if (dd != System.Windows.Forms.DialogResult.OK) return;

            ArquiDirAtual = Path.GetDirectoryName(ofdFonte.FileName);
            ArquiNomeAtual = Path.GetFileNameWithoutExtension(ofdFonte.FileName);

            FileStream fsFonte = new FileStream(ofdFonte.FileName, FileMode.Open);
            BinaryReader brFonte = new BinaryReader(fsFonte);
            //StreamReader srFonte = new StreamReader(ofdFonte.FileName);

            // criar programa do arquivo
            try
            {
                ArquiCongruente = false;   // em caso de exceção, desconhecido
                MON.LerProg(brFonte);
                //ProcAtual = MON.PROG.TipoProc;

                ProtT.AipTxt(MON.ItemProtocolo);
                ArquiCongruente = true;
                ArquiPersistente = true;
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message, "Exceção doida");
            }
            finally
            {
                brFonte.Close();
                fsFonte.Close();
            }
            ArquiCongruente = true;
            ArquiPersistente = true;

        // vincular com data grid view
        if (LIN != null) this.Controls.Remove(LIN);
        LIN = new dgvLinhas(MON.PROG.TipoProc, MON.PROG.Linhas, ResetCongru);
        this.Controls.Add(LIN);
        }
        private void salvarComoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // selecionar arquivo fonte e gravar programa átual no arquivo

            OpenFileDialog ofdFonte = new OpenFileDialog();

            ofdFonte.AddExtension = true;
            ofdFonte.CheckFileExists = false;
            ofdFonte.CheckPathExists = true;
            ofdFonte.DefaultExt = ArquiFonteExt;
            ofdFonte.Multiselect = false;
            ofdFonte.RestoreDirectory = true;
            ofdFonte.Title = "Abrir arquivo fonte do Montador-J5";
            ofdFonte.ValidateNames = true;

            if (ArquiDirAtual != "") ofdFonte.InitialDirectory = ArquiDirAtual;
            DialogResult dd = ofdFonte.ShowDialog();

            if (dd != System.Windows.Forms.DialogResult.OK) return;

            FileStream fsx = new FileStream(ofdFonte.FileName, FileMode.OpenOrCreate);
            BinaryWriter bwFonte = new BinaryWriter(fsx);


            // criar programa do arquivo
            try
            {
                MON.GravProg(bwFonte);
                ProtT.AipTxt(MON.ItemProtocolo);
                ArquiPersistente = true;
                ArquiCongruente = true;
            }
            catch (Exception)
            {
                MessageBox.Show("Exceção doida");
            }
            finally
            {
                bwFonte.Close();
                fsx.Close();
            }
        }
        private void salvarToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // gravar programa fonte em arquivo conhecido
            if (!ArquiPersistente)
            {
                // falta info para onde gravar
                salvarComoToolStripMenuItem_Click(sender, e);
                return;
            }

            string fn = ArquiDirAtual + "\\" + ArquiNomeAtual + "." + ArquiFonteExt;
            FileStream fsx = new FileStream(fn, FileMode.OpenOrCreate);
            BinaryWriter bwFonte = new BinaryWriter(fsx);


            // criar programa do arquivo
            try
            {
                MON.GravProg(bwFonte);
                ProtT.AipTxt(MON.ItemProtocolo);
                ArquiPersistente = true;
                ArquiCongruente = true;
            }
            catch (Exception)
            {
                MessageBox.Show("Exceção doida");
            }
            finally
            {
                bwFonte.Close();
                fsx.Close();
            }
        }
        private void fecharToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // fechar programa fonte
        }

        // menu produçaõ
        //
        private void montarToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AtuOPM(ref OPM);  
            MON.Montar(OPM);
            ProtT.AipTxt(MON.ItemProtocolo);
        }

        // menu objeto
        //
        private void salvarComoToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            // salvar objeto relocavel
            OpenFileDialog ofdFonte = new OpenFileDialog();

            ofdFonte.Title = "Abrir arquivo objeto relocavel do Montador-J5";
            ofdFonte.AddExtension = true;
            ofdFonte.CheckFileExists = false;
            ofdFonte.CheckPathExists = true;
            ofdFonte.Multiselect = false;
            ofdFonte.RestoreDirectory = true;
            ofdFonte.ValidateNames = true;

            ofdFonte.DefaultExt = ArquiReloExt;
            if (ArquiDirAtual != "")
            {
                ofdFonte.InitialDirectory = ArquiDirAtual;
                if (ArquiNomeAtual != "") ofdFonte.FileName = ArquiNomeAtual;
            }

            DialogResult dd = ofdFonte.ShowDialog();
            if (dd != System.Windows.Forms.DialogResult.OK) return;
            if (!MON.TemObjRelo)
            {
                MessageBox.Show("Não tem objeto relocavel.");
                return;
            }

            FileStream fsx = new FileStream(ofdFonte.FileName, FileMode.Create);  // acabar com arquivo velho se existe
            BinaryWriter bwObj = new BinaryWriter(fsx);

            // criar objeto em arquivo
            try
            {
                MON.GravObjRelo(bwObj);
                ProtT.AipTxt(MON.ItemProtocolo);
            }
            catch (Exception)
            {
                MessageBox.Show("Exceção doida");
            }
            finally
            {
                bwObj.Close();
                fsx.Close();
            }

        }
        private void abrirObjetoRelocavelToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // abrir objeto relocavel
        }
        private void salvarObjetoExecutavelToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // salvar objeto executavel
        }

        // menu Lista
        //
        private void mostrarToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // mostar Lista
            AtuOPL(ref OPL);  // opções de geração da lista átual
            MON.ListarResultados(OPL);
            LIS = null;
            LIS = new frmList();
            LIS.txtLista.Text = MON.Lista;
            LIS.Show();
            LIS.Refresh();  // unfreeze scroll bar??
        }
        // ..... setar/resetar opções da lista
        private void protocoloToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (sender as ToolStripMenuItem).Checked = !(sender as ToolStripMenuItem).Checked;
        }
        private void fonteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (sender as ToolStripMenuItem).Checked = !(sender as ToolStripMenuItem).Checked;
        }
        private void fonteComObservaçõesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (sender as ToolStripMenuItem).Checked = !(sender as ToolStripMenuItem).Checked;
        }
        private void observaçõesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (sender as ToolStripMenuItem).Checked = !(sender as ToolStripMenuItem).Checked;
        }
        private void símbolosToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (sender as ToolStripMenuItem).Checked = !(sender as ToolStripMenuItem).Checked;
        }
        private void símbolosComReferênciaCrusadaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (sender as ToolStripMenuItem).Checked = !(sender as ToolStripMenuItem).Checked;
        }
        private void objetoRelocavelToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (sender as ToolStripMenuItem).Checked = !(sender as ToolStripMenuItem).Checked;
        }
        private void fonteComObjetoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (sender as ToolStripMenuItem).Checked = !(sender as ToolStripMenuItem).Checked;
        }
        private void debugToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Produção/Debug
            (sender as ToolStripMenuItem).Checked = !(sender as ToolStripMenuItem).Checked;
        }
        private void tabelaDeSímbolosToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Produção/Tabela de Símbolos
            (sender as ToolStripMenuItem).Checked = !(sender as ToolStripMenuItem).Checked;
        }

        // Métodos auxiliares ====================================
        //
        // 
        void ResetCongru()
        {
            // metodo serve para ser passado como delegate às instâncias do dgvLinhas
            ArquiCongruente = false;
        }
        void AtuOPM(ref OpcMont prmOPM)
        {
            prmOPM.Debug = debugToolStripMenuItem.Checked;
            prmOPM.TblSimbo = tabelaDeSímbolosToolStripMenuItem.Checked;
        }
        void AtuOPL(ref optLista prmOPL)
        {
            prmOPL.Protocolo = protocoloToolStripMenuItem.Checked;
            prmOPL.Fonte = fonteToolStripMenuItem.Checked | fonteComObservaçõesToolStripMenuItem.Checked;
            prmOPL.ComObs = fonteComObservaçõesToolStripMenuItem.Checked;
            prmOPL.Observacoes = observaçõesToolStripMenuItem.Checked;
            prmOPL.Simbolos = símbolosToolStripMenuItem.Checked | símbolosComReferênciaCrusadaToolStripMenuItem.Checked;
            prmOPL.ComXref = símbolosComReferênciaCrusadaToolStripMenuItem.Checked;
            prmOPL.Objeto = objetoRelocavelToolStripMenuItem.Checked | fonteComObjetoToolStripMenuItem.Checked;
            prmOPL.ComFonte = fonteComObjetoToolStripMenuItem.Checked;
        }


    }
}
